package org.iweb.init.classloader;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class IWebClassLoader extends URLClassLoader{

	//private URLClassLoader[] loaders;

	private static String[] paths=new String[]{
		System.getProperty("catalina.base")+"/webapps/iweb-core/WEB-INF/dynlib",
		System.getProperty("catalina.base")+"/webapps/iweb-core/WEB-INF/lib"};

	private static Logger log=LoggerFactory.getLogger(IWebClassLoader.class);

    public IWebClassLoader(ClassLoader parent) {

    	super(new URL[0], parent);

    	reload();
    }

    protected void reload(){

    	//loaders=new URLClassLoader[paths.length];

    	for(int i=0;i<paths.length;i++){
    		//loaders[i]=new URLClassLoader(new URL[0],this);

    		File[] list=new File(paths[i]).listFiles(new FileFilter() {

    			@Override
    			public boolean accept(File pathname) {
    				return pathname.getName().endsWith(".jar");
    			}
    		});

    		if(list!=null){

	    		Arrays.asList(list).forEach(jar->{
	    			try {
	    				ClassLoaderUtil.addURL(jar.toURI().toURL(), this);//loaders[i]);
	    			} catch (IOException e) {
	    				// TODO Auto-generated catch block
	    				e.printStackTrace();
	    			}
	    		});
    		}
    	}

    	// find in the thread classloader
    	ClassLoader classLoader = Thread.currentThread()
				.getContextClassLoader();
    	try {
			Enumeration<URL> resources = classLoader.getResources("");
			while (resources.hasMoreElements()) {

				URL resource = resources.nextElement();
				//dirs.add(new File(resource.getFile()));

				ClassLoaderUtil.addURL(resource, this);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
    	try{
    		//if(name.startsWith("java."))
    		return super.loadClass(name);
    		//return findClass(name);
    	}catch(ClassNotFoundException e){
    		//e.printStackTrace();
    		log.error("Class not found in java classloader: "+name);

    	}

//    	for(URLClassLoader loader: loaders){
//    		try{
//        		//if(name.startsWith("java."))
//        		return loader.loadClass(name);
//        		//return findClass(name);
//        	}catch(ClassNotFoundException e){
//        		e.printStackTrace();
//        		log.error("Class not found in java classloader: "+name);
//        	}
//    	}

    	return null;

    	//return IWebGroovyEngine.getClassLoader().loadClass(name);
    }

//    public ClassLoader getGroovyClassLoader(){
//    	return IWebGroovyEngine.getClassLoader();
//    }


//    @SuppressWarnings({ "rawtypes", "unchecked" })
//	public Class loadClass(String name) throws ClassNotFoundException {
//    	if(name.startsWith("java."))
//    		return super.loadClass(name);
//
//        try {
//
//            String url = "file:/Users/dmac/Documents/workspace/ee_4_3/TestClassReload/build/classes/org/prj/MyObject.class";
//            URL myUrl = new URL(url);
//            URLConnection connection = myUrl.openConnection();
//            InputStream input = connection.getInputStream();
//            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
//            int data = input.read();
//
//            while(data != -1){
//                buffer.write(data);
//                data = input.read();
//            }
//
//            input.close();
//
//            byte[] classData = buffer.toByteArray();
//
//
//
//            return defineClass(name,
//                    classData, 0, classData.length);
//
//        } catch (MalformedURLException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return null;
//    }

    @Override
    public URL[] getURLs() {
    	List<URL> urls=new LinkedList<>();

    	urls.addAll(Arrays.asList(super.getURLs()));

//    	for(URLClassLoader loader: loaders){
//    		urls.addAll(Arrays.asList(loader.getURLs()));
//    	}

    	URL[] result=new URL[urls.size()];

    	result=urls.toArray(result);

    	return result;
    }

}